/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.web30.util;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.mozilla.intl.chardet.HtmlCharsetDetector;
import org.mozilla.intl.chardet.nsDetector;
import org.mozilla.intl.chardet.nsICharsetDetectionObserver;

/**
 *
 * @author xiazy
 */
public class EncodeDetector {

    static private boolean _found = false;
    static private String _charsetName;

    static public String detectEncode(byte[] bytes) {
        _found = false;
        _charsetName = "";
        nsDetector det = new nsDetector(2);
        // The Notify() will be called when a matching charset is found.
        det.Init(new nsICharsetDetectionObserver() {

            @Override
            public void Notify(String charset) {
                HtmlCharsetDetector.found = true;
                _charsetName = charset;
                _found = true;
            }
        });
        boolean isAscii = true;
        isAscii = det.isAscii(bytes, bytes.length);
        if (isAscii == false) {
            boolean ret = det.DoIt(bytes, bytes.length, false);
            if (ret == false) {
                det.DataEnd();
            }
        } else {
            _found = true;
            _charsetName = "US-ASCII";
        }
        if (!_found) {
            String prob[] = det.getProbableCharsets();
            for (int i = 0; i < prob.length; i++) {
                if (prob[i].indexOf("GB") != -1) {
                    _charsetName = "GBK";
                    break;
                } else if (prob[i].indexOf("UTF-8") != -1) {
                    _charsetName = "UTF-8";
                    break;
                }
            }
        }
        return _charsetName;
    }

    /**
     *
     * @param stream
     */
    static public String detectEncode(InputStream stream) {
        try {
            if (stream == null) {
                return null;
            }
            // means detect Chinese
            nsDetector det = new nsDetector(2);
            // The Notify() will be called when a matching charset is found.
            det.Init(new nsICharsetDetectionObserver() {

                @Override
                public void Notify(String charset) {
                    HtmlCharsetDetector.found = true;
                    _found = true;
                    _charsetName = charset;
                }
            });
            BufferedInputStream imp = new BufferedInputStream(stream);
            byte[] buf = new byte[1024];
            int len;
            boolean done = false;
            boolean isAscii = true;
            while ((len = imp.read(buf, 0, buf.length)) != -1) {
                // Check if the stream is only ascii.
                if (isAscii) {
                    isAscii = det.isAscii(buf, len);
                }
                if (!isAscii && !done) {
                    done = det.DoIt(buf, len, false);
                }
            }
            det.DataEnd();
            if(isAscii){
                return "US-ASCII";
            }
            if (!_found) {
                String prob[] = det.getProbableCharsets();
                for (int i = 0; i < prob.length; i++) {
                    if (prob[i].indexOf("GB") != -1) {
                        _charsetName = "GBK";
                        break;
                    } else if (prob[i].indexOf("UTF-8") != -1) {
                        _charsetName = "UTF-8";
                        break;
                    }
                }
            }
            return _charsetName;

        } catch (IOException ex) {
            Logger.getLogger(EncodeDetector.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }
}
